using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Diagnostics;

namespace DocumentCreationSystem.Services
{
    /// <summary>
    /// 工具执行监控服务接口
    /// </summary>
    public interface IToolExecutionMonitor
    {
        /// <summary>
        /// 开始监控工具执行
        /// </summary>
        string StartExecution(string toolName, Dictionary<string, object> parameters);

        /// <summary>
        /// 结束监控工具执行
        /// </summary>
        void EndExecution(string executionId, bool success, string? errorMessage = null);

        /// <summary>
        /// 记录执行步骤
        /// </summary>
        void LogStep(string executionId, string stepName, string description);

        /// <summary>
        /// 获取执行统计信息
        /// </summary>
        ToolExecutionStatistics GetStatistics(string toolName);

        /// <summary>
        /// 获取所有工具的统计信息
        /// </summary>
        Dictionary<string, ToolExecutionStatistics> GetAllStatistics();

        /// <summary>
        /// 获取当前正在执行的工具
        /// </summary>
        List<ActiveExecution> GetActiveExecutions();

        /// <summary>
        /// 清理过期的执行记录
        /// </summary>
        void CleanupExpiredRecords();

        /// <summary>
        /// 工具执行事件
        /// </summary>
        event EventHandler<ToolExecutionEventArgs>? ExecutionEvent;
    }

    /// <summary>
    /// 工具执行监控服务实现
    /// </summary>
    public class ToolExecutionMonitor : IToolExecutionMonitor
    {
        private readonly ILogger<ToolExecutionMonitor> _logger;
        private readonly ConcurrentDictionary<string, ExecutionRecord> _activeExecutions = new();
        private readonly ConcurrentDictionary<string, ToolExecutionStatistics> _statistics = new();
        private readonly Timer _cleanupTimer;

        public event EventHandler<ToolExecutionEventArgs>? ExecutionEvent;

        public ToolExecutionMonitor(ILogger<ToolExecutionMonitor> logger)
        {
            _logger = logger;
            
            // 每5分钟清理一次过期记录
            _cleanupTimer = new Timer(CleanupCallback, null, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(5));
        }

        public string StartExecution(string toolName, Dictionary<string, object> parameters)
        {
            var executionId = Guid.NewGuid().ToString();
            var record = new ExecutionRecord
            {
                ExecutionId = executionId,
                ToolName = toolName,
                Parameters = parameters,
                StartTime = DateTime.Now,
                Stopwatch = Stopwatch.StartNew(),
                Steps = new List<ExecutionStep>()
            };

            _activeExecutions[executionId] = record;

            // 更新统计信息
            var stats = _statistics.GetOrAdd(toolName, _ => new ToolExecutionStatistics { ToolName = toolName });
            stats.TotalExecutions++;
            stats.ActiveExecutions++;

            _logger.LogInformation($"开始执行工具: {toolName}, 执行ID: {executionId}");

            // 触发事件
            ExecutionEvent?.Invoke(this, new ToolExecutionEventArgs
            {
                EventType = ToolExecutionEventType.Started,
                ExecutionId = executionId,
                ToolName = toolName,
                Timestamp = DateTime.Now
            });

            return executionId;
        }

        public void EndExecution(string executionId, bool success, string? errorMessage = null)
        {
            if (!_activeExecutions.TryRemove(executionId, out var record))
            {
                _logger.LogWarning($"未找到执行记录: {executionId}");
                return;
            }

            record.Stopwatch.Stop();
            record.EndTime = DateTime.Now;
            record.Success = success;
            record.ErrorMessage = errorMessage;

            var duration = record.Stopwatch.ElapsedMilliseconds;

            // 更新统计信息
            if (_statistics.TryGetValue(record.ToolName, out var stats))
            {
                stats.ActiveExecutions--;

                if (success)
                {
                    stats.SuccessfulExecutions++;
                }
                else
                {
                    stats.FailedExecutions++;
                }

                // 更新平均执行时间
                lock (stats)
                {
                    stats.TotalExecutionTime += duration;
                    stats.AverageExecutionTime = stats.TotalExecutionTime / stats.TotalExecutions;
                    
                    if (duration > stats.MaxExecutionTime)
                        stats.MaxExecutionTime = duration;
                    
                    if (stats.MinExecutionTime == 0 || duration < stats.MinExecutionTime)
                        stats.MinExecutionTime = duration;

                    stats.LastExecutionTime = DateTime.Now;
                }
            }

            _logger.LogInformation($"结束执行工具: {record.ToolName}, 执行ID: {executionId}, " +
                                 $"耗时: {duration}ms, 成功: {success}");

            // 触发事件
            ExecutionEvent?.Invoke(this, new ToolExecutionEventArgs
            {
                EventType = success ? ToolExecutionEventType.Completed : ToolExecutionEventType.Failed,
                ExecutionId = executionId,
                ToolName = record.ToolName,
                Duration = duration,
                ErrorMessage = errorMessage,
                Timestamp = DateTime.Now
            });
        }

        public void LogStep(string executionId, string stepName, string description)
        {
            if (_activeExecutions.TryGetValue(executionId, out var record))
            {
                var step = new ExecutionStep
                {
                    StepName = stepName,
                    Description = description,
                    Timestamp = DateTime.Now,
                    ElapsedTime = record.Stopwatch.ElapsedMilliseconds
                };

                lock (record.Steps)
                {
                    record.Steps.Add(step);
                }

                _logger.LogDebug($"工具执行步骤: {record.ToolName}[{executionId}] - {stepName}: {description}");

                // 触发事件
                ExecutionEvent?.Invoke(this, new ToolExecutionEventArgs
                {
                    EventType = ToolExecutionEventType.StepCompleted,
                    ExecutionId = executionId,
                    ToolName = record.ToolName,
                    StepName = stepName,
                    StepDescription = description,
                    Timestamp = DateTime.Now
                });
            }
        }

        public ToolExecutionStatistics GetStatistics(string toolName)
        {
            return _statistics.GetOrAdd(toolName, _ => new ToolExecutionStatistics { ToolName = toolName });
        }

        public Dictionary<string, ToolExecutionStatistics> GetAllStatistics()
        {
            return _statistics.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
        }

        public List<ActiveExecution> GetActiveExecutions()
        {
            return _activeExecutions.Values.Select(record => new ActiveExecution
            {
                ExecutionId = record.ExecutionId,
                ToolName = record.ToolName,
                StartTime = record.StartTime,
                ElapsedTime = record.Stopwatch.ElapsedMilliseconds,
                CurrentStep = record.Steps.LastOrDefault()?.StepName ?? "初始化",
                Parameters = record.Parameters
            }).ToList();
        }

        public void CleanupExpiredRecords()
        {
            var expiredThreshold = DateTime.Now.AddHours(-1); // 1小时前的记录
            var expiredExecutions = _activeExecutions.Values
                .Where(record => record.StartTime < expiredThreshold)
                .ToList();

            foreach (var record in expiredExecutions)
            {
                if (_activeExecutions.TryRemove(record.ExecutionId, out _))
                {
                    _logger.LogWarning($"清理过期的执行记录: {record.ToolName}[{record.ExecutionId}]");
                    
                    // 标记为超时失败
                    EndExecution(record.ExecutionId, false, "执行超时");
                }
            }
        }

        private void CleanupCallback(object? state)
        {
            try
            {
                CleanupExpiredRecords();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理过期记录时发生错误");
            }
        }

        public void Dispose()
        {
            _cleanupTimer?.Dispose();
        }
    }

    /// <summary>
    /// 执行记录
    /// </summary>
    internal class ExecutionRecord
    {
        public string ExecutionId { get; set; } = string.Empty;
        public string ToolName { get; set; } = string.Empty;
        public Dictionary<string, object> Parameters { get; set; } = new();
        public DateTime StartTime { get; set; }
        public DateTime? EndTime { get; set; }
        public Stopwatch Stopwatch { get; set; } = new();
        public bool Success { get; set; }
        public string? ErrorMessage { get; set; }
        public List<ExecutionStep> Steps { get; set; } = new();
    }

    /// <summary>
    /// 执行步骤
    /// </summary>
    public class ExecutionStep
    {
        public string StepName { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public DateTime Timestamp { get; set; }
        public long ElapsedTime { get; set; }
    }

    /// <summary>
    /// 工具执行统计信息
    /// </summary>
    public class ToolExecutionStatistics
    {
        public string ToolName { get; set; } = string.Empty;
        public long TotalExecutions { get; set; }
        public long SuccessfulExecutions { get; set; }
        public long FailedExecutions { get; set; }
        public long ActiveExecutions { get; set; }
        public long TotalExecutionTime { get; set; }
        public double AverageExecutionTime { get; set; }
        public long MinExecutionTime { get; set; }
        public long MaxExecutionTime { get; set; }
        public DateTime? LastExecutionTime { get; set; }
        public double SuccessRate => TotalExecutions > 0 ? (double)SuccessfulExecutions / TotalExecutions : 0;
    }

    /// <summary>
    /// 活动执行
    /// </summary>
    public class ActiveExecution
    {
        public string ExecutionId { get; set; } = string.Empty;
        public string ToolName { get; set; } = string.Empty;
        public DateTime StartTime { get; set; }
        public long ElapsedTime { get; set; }
        public string CurrentStep { get; set; } = string.Empty;
        public Dictionary<string, object> Parameters { get; set; } = new();
    }

    /// <summary>
    /// 工具执行事件参数
    /// </summary>
    public class ToolExecutionEventArgs : EventArgs
    {
        public ToolExecutionEventType EventType { get; set; }
        public string ExecutionId { get; set; } = string.Empty;
        public string ToolName { get; set; } = string.Empty;
        public long Duration { get; set; }
        public string? ErrorMessage { get; set; }
        public string? StepName { get; set; }
        public string? StepDescription { get; set; }
        public DateTime Timestamp { get; set; }
    }

    /// <summary>
    /// 工具执行事件类型
    /// </summary>
    public enum ToolExecutionEventType
    {
        Started,
        StepCompleted,
        Completed,
        Failed,
        Timeout
    }
}
